#include <ctype.h>
#include "project.h"
#include <iostream>
#include "stdio.h"
#include <vector>

#include "com_parse_data.h"
#include "driver_usart.h"
#include "project.h"

std::vector<uint8_t> cache_buffer;

int32 parse_data_crc(uint8 chect_data1, uint8 chect_data2, uint8 result)
{
    // crc16Data = dataBuf[5]; // 计算 CRC部分
    // crc16Data = (crc16Data << 8) + dataBuf[6];
    // uint16_t recvCRC16 = CRC16_Table(load_data);
    // if(recvCRC16 != crc16Data){
    //     spdlog::info("Imu load data is error, crc is wrong !");
    //     return REV_ERROR;
    // }
    // return RECV_IMU;
    return REV_ERR;
}


int32 parse_data_sum(uint8_t *load_buf, uint32 data_len, uint8 chect_result)
{
    uint32 i = 0;
    uint8 sum_result = 0;

    for (i = 0; i < data_len; i++) {
        sum_result += load_buf[i];
    }

    if (sum_result == chect_result) {
        return REV_OK;
    }
    return REV_ERR;
}

int32 com_parse_data(uint8 *dataBuf)
{
    uint32_t load_data_len = 0;// 负载数据的长度
    uint16_t crc16Data = 0;
    int32 check_result = 0;
    std::vector<uint8> data_load;

    return REV_ERR;
}


int32 findData(std::vector<uint8_t> &dataBuf, int8_t data, int16_t startLocate)
{
    for(int i=startLocate; i<dataBuf.size(); i++){
        if(data == dataBuf[i]){
            // GUA_LOGI("findData data[%x] dataBuf[%x]\n", data, i, dataBuf[i]);
            return i;
        }
    }
    return -1;
}

int32 getUsartData(uint8_t *dataBuf, SerialDriver * serial, PARASE_BUFFER_STRUCT *data_structure)
{
    /*数据帧寻找方法：
    程序开始有空的固定数据缓冲器buf，如果有接收到数据就将数据储插入到固定的缓冲区buf的最后面的位置。
    到数据帧头和帧尾的位置，将完整的数据帧保存到函数输出缓冲器中，作为函数的本次输出结果。
    将这次找到的数据帧尾到结束的位置到这一次接收的数据的最后位置的这些剩余所有数据都转存到临时buf中，
    再将固定缓冲区中的buf内容替换成临时buf的内容，等待下一次数据*/
    std::vector<uint8_t> data_buffer;
    uint8_t load_buf[256] = {0};
    std::vector<uint8_t> tempBuf;
    std::vector<uint8_t> reamin_buffer; // 存放剩余数据
    uint32_t headLocate = 0;
    uint32_t endLocate = 0;
    uint32_t payloadNum = 0;
    int32_t rev = 0;

    /* 接受串口的数据*/
    int32_t read_result = serial->ReadBytes(data_buffer, 0, 10);
    if(read_result == RECV_DONE){
        cache_buffer.insert(cache_buffer.end(), data_buffer.begin(), data_buffer.end());
    } else if(read_result == REV_ERROR){
        return REV_ERROR;
    }
    data_buffer.clear();
    data_buffer.shrink_to_fit();

    /* 寻找cache buffer内的数据包的位置,根据包头和包尾确定整体的位置 */
    if (cache_buffer.size() > 0) { // 由于接受函数从程序开始一直会执行，所以需要通过判断是否有数据决定是否返回数据
        headLocate = findData(cache_buffer, data_structure->head, 0);
        if(headLocate != -1){
            endLocate = findData(cache_buffer, data_structure->end, headLocate+1);
            if(endLocate == -1){
                return REV_NULL;
            }
        } else {
            return REV_NULL;
        }

        if (endLocate < headLocate+4) {
            return REV_NULL;
        }

        payloadNum = cache_buffer[headLocate + 1]; // 数据段的长度
        uint32_t totalBufLen = sizeof(data_structure->head) + sizeof(data_structure->len) + payloadNum + data_structure->check_len + 3;
        // GUA_LOGI("totalBufLen: %d payloadNum:[%d] endLocate:[%d] headLocate:[%d] [%d]\n", totalBufLen, payloadNum, endLocate, headLocate, endLocate - headLocate + 1);
        if (totalBufLen == (endLocate - headLocate + 1)) { // 如果固定的位置没有数据结束位说明数据是有问题的
            // 输出最终数据
            tempBuf.insert(tempBuf.end(),  cache_buffer.begin() + headLocate, cache_buffer.begin() + headLocate + totalBufLen);
            for (int i=0; i<payloadNum; i++) {
                // load_buf.insert(load_buf.end(), tempBuf[i+2]);
                load_buf[i] = tempBuf[i+2];
            }

            // GUA_LOGI("check:[0X%02x] totalBufLen:[%d] payloadNum:[%d] load_buf:[%s]\n", tempBuf[totalBufLen-3], totalBufLen, payloadNum, load_buf);
            rev = parse_data_sum(load_buf, payloadNum, tempBuf[totalBufLen-3]);
            if (rev == REV_OK) {
                // dataBuf.insert(dataBuf.begin(), load_buf.begin(), load_buf.end());
                // GUA_LOGI("ok[%s]\n", load_buf);
                memcpy(dataBuf, load_buf, payloadNum);
            }

            tempBuf.clear();
            tempBuf.shrink_to_fit();
            //转存剩余的数据
            reamin_buffer.insert(reamin_buffer.end(), cache_buffer.begin() + headLocate + totalBufLen, cache_buffer.end());
            cache_buffer = reamin_buffer;
            // GUA_LOGI("cache_buffer[%d] get data:%s\n", cache_buffer.size(), dataBuf.data());
            return RECV_DONE;
        } else {
            cache_buffer = reamin_buffer; // 更新储存内存
            return REV_NULL;
        }
    }
    return REV_NULL;
}